﻿//-----------------------------------------------------------------------
// <copyright file="Navigation.cs" company="Microsoft Corporation">
//     Copyright Microsoft Corporation. All Rights Reserved. This code released under the terms of the Microsoft Public License (MS-PL, http://opensource.org/licenses/ms-pl.html.) This is sample code only, do not use in production environments.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.ALMRangers.VsarTreasureMap.WindowsStoreApp
{
    using System;
    using System.Collections.Generic;
    using Microsoft.ALMRangers.VsarTreasureMap.WindowsStoreApp.ViewModels;
    using Windows.UI.Core;
    using Windows.UI.Xaml.Controls;

    /// <summary>
    /// Class that deals with the navigation events of the app.
    /// </summary>
    public static class Navigation
    {
        /// <summary>
        /// Stores the navigation sequence of the user through the app.
        /// </summary>
        private static Stack<Tuple<Type, object>> backStack = new Stack<Tuple<Type, object>>();

        /// <summary>
        /// Gets or sets the Root Frame used for navigation.
        /// </summary>
        public static Frame RootFrame { get; set; }

        /// <summary>
        /// Gets a value indicating whether the application can navigate back based on back stack size.
        /// </summary>
        public static bool CanGoBack
        {
            get
            {
                return backStack.Count >= 2;
            }
        }

        /// <summary>
        /// Attempts to navigate back based on what is in the back stack
        /// </summary>
        public static void GoBack()
        {
            if (!CanGoBack)
            {
                return;
            }

            backStack.Pop(); // remove current page 
            var last = backStack.Pop();
            Navigate(last.Item1, last.Item2);
        }

        /// <summary>
        /// Attempts to navigate the root frame to a new page.
        /// </summary>
        /// <param name="page">Type of page to navigate to.</param>
        /// <param name="parameter">Parameter to pass to the constructor of a page to be navigated to.</param>
        /// <param name="addToBackStack">True for should add to the back stack.</param>
        public static void Navigate(Type page, object parameter = null, bool addToBackStack = true)
        {
            if (addToBackStack)
            {
                backStack.Push(Tuple.Create(page, parameter));
            }

            var @namespace = page.Namespace;
            var mode = Windows.UI.ViewManagement.ApplicationView.Value.ToString();
            var name = page.Name;

            var modePage = @namespace + "." + mode + "." + name;

            var pageType = Type.GetType(modePage);
            if (pageType == null)
            {
                pageType = page;
            }

            var currentPage = RootFrame.Content as Page;
            if (currentPage != null)
            {
                var share = currentPage.DataContext as IShare;
                if (share != null)
                {
                    share.Deregister();
                }
            }

            if (parameter == null)
            {
                RootFrame.Navigate(pageType);
            }
            else
            {
                RootFrame.Navigate(pageType, parameter);
            }
        }

        /// <summary>
        /// Reloads the current page
        /// </summary>
        internal static void ReloadCurrentPage()
        {
            var last = backStack.Peek();
            Navigate(last.Item1, last.Item2, false);
        }
    }
}
